import { ElOption, ElSelect } from 'element-plus';
import { PropType } from 'vue';
import { useDispatchBubbles } from '../Drawer/store';
import { useFormMode } from '../Form/mode';
import './index.scss';

type TOptionValue = string | number | boolean | object;

export interface IOption {
  /** 选项的值 */
  value: TOptionValue;
  /** 选项的标签，若不设置则默认与value相同 */
  label: string | number;
  /** 二级label */
  subLabel?: string | number;
  /** 是否禁用该选项 */
  disabled?: boolean;
  children?: IOption[];
}

export const mciSelectProps = {
  list: {
    type: Array as PropType<IOption[]>,
    default: () => []
  },
  // 只有下边框单边线
  singleLine: {
    type: Boolean,
    default: false
  },
  // 显示模式
  mode: {
    type: String as PropType<TVitalModeType>,
    default: ''
  },
  disabled: {
    type: Boolean,
    default: false
  },
  placeholder: {
    type: String,
    default: '请选择'
  },
  clearable: {
    type: Boolean,
    default: false
  },
  multiple: {
    type: Boolean,
    default: false
  },
  filterable: {
    type: Boolean,
    default: false
  },
  allowCreate: {
    type: Boolean,
    default: false
  },
  collapseTags: {
    type: Boolean,
    default: false
  },
  maxCollapseTags: {
    type: Number,
    default: 1
  },
  size: {
    type: String,
    default: 'default'
  },
  modelValue: {
    type: [String, Number, Boolean, Object, Array],
    default: ''
  }
};

export const mciSelectEmits = ['loadmore', 'update:modelValue'];

export const resolveMciSelectPropsAndEmits = () => ({
  props: { ...mciSelectProps },
  emits: [...mciSelectEmits]
});

export const MciSelect = defineComponent({
  name: 'MciSelect',
  directives: {
    loadmore: {
      mounted(el, binding) {
        const scrollDom = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap');
        scrollDom?.addEventListener('scroll', ({ target }: any) => {
          const loadOpen = target.scrollHeight - target.scrollTop <= target.clientHeight;
          if (loadOpen) {
            binding.value();
          }
        });
      }
    }
  },
  props: {
    ...mciSelectProps
  },
  emits: [...mciSelectEmits],
  setup(props, { emit }) {
    const formMode = useFormMode();
    const modeComputed = computed(() => formMode?.mode || props.mode);
    const root = ref(null as any);
    const { dispatchBubbleChange } = useDispatchBubbles();

    const loadMore = () => {
      emit('loadmore');
    };

    return {
      dispatchBubbleChange,
      modeComputed,
      root,
      loadMore
    };
  },
  render() {
    const { singleLine, list, modeComputed } = this;
    if (modeComputed === 'view') {
      return <div class="mci-select_view">{this.list.find((item) => item.value === this.modelValue)?.label ?? (this.modelValue || '-')}</div>;
    }

    const disableAttrs = modeComputed === 'disable' || this.disabled ? { disabled: true } : {};
    const createOptions = () => {
      return list.map((option) => {
        if (option.subLabel) {
          return (
            <ElOption class="is-subOption" key={option.value + ''} {...option}>
              <label>{option.label}</label>
              <p class="text-label-14 pb-4 bd-b">{option.subLabel}</p>
            </ElOption>
          );
        }
        return <ElOption key={option.value + ''} {...option} />;
      });
    };

    return (
      <ElSelect
        ref="root"
        allowCreate={this.allowCreate}
        onChange={this.dispatchBubbleChange}
        class={['mci-select', { 'mci-single-line': singleLine }]}
        {...disableAttrs}
        modelValue={this.modelValue}
        onUpdate:modelValue={(val) => this.$emit('update:modelValue', val)}
        placeholder={this.placeholder}
        clearable={this.clearable}
        multiple={this.multiple}
        collapse-tags={this.collapseTags}
        max-collapse-tags={this.maxCollapseTags}
        vSlots={this.$slots}
        v-loadmore={this.loadMore}
        filterable={this.filterable}
        size={this.size}>
        {createOptions()}
      </ElSelect>
    );
  }
});

export const MciOption = ElOption;
